﻿
namespace HSS.Xaml.UI.Controls
{
	#region Using Directives
	using System.Collections.Generic;
	using System.Linq;
	using System.Windows;
	using System.Windows.Controls;
	using System.Windows.Markup;
	using System.Windows.Media;
	using System.Windows.Shapes;
	using HSS.ComponentModel;
	using HSS.Xaml.UI.Data;
	using HSS.Xaml.UI.Media;
	#endregion

	#region ColorValueEditor
	/// <summary>
	/// An Editor that support the Color Type
	/// </summary>
	public class ColorValueEditor : AutoCompleteBoxEditorBase
	{
		#region Fields
		ColorConverter colorConverter = new ColorConverter();
		#endregion

		#region Constructors
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="descriptor">The HSSPropertyDescriptor being viewed</param>
		public ColorValueEditor(HSSPropertyDescriptor descriptor)
			: base(descriptor)
		{
		}
		#endregion

		#region Properties

		#region SelectedColor
		/// <summary>
		/// Gets the Selected Color
		/// </summary>
		public Color SelectedColor
		{
			get { return (Color)GetValue(SelectedColorProperty); }
			set { SetValue(SelectedColorProperty, value); }
		}
		/// <summary>
		/// Using a DependencyProperty as the backing store for SelectedColor.  This enables animation, styling, binding, etc...
		/// </summary>
		public static readonly DependencyProperty SelectedColorProperty =
			DependencyProperty.Register("SelectedColor", typeof(Color), typeof(ColorValueEditor), new PropertyMetadata((Color)KnownColor.UnknownColor));
		#endregion

		/// <summary>
		/// A visual que as to the actual appearance of the color
		/// </summary>
		protected Rectangle ColorIndicator
		{
			get;
			private set;
		}

		#endregion

		#region Overrides

		/// <summary>
		/// Perform additional editor initialization.
		/// </summary>
		protected override void OnInitialized()
		{
			base.OnInitialized();
			var c = (Color)this.Object;
			this.ColorIndicator = new Rectangle
			{
				Margin = new Thickness(0),
				Fill = new SolidColorBrush(c),
				Height = 12,
				Width = 20
			};
			this.PropertyEntry.ValueControl.CustomContent = new Border
			{
				CornerRadius = new CornerRadius(2),
				Background = new SolidColorBrush(KnownColor.White),
				BorderBrush = new SolidColorBrush(KnownColor.Black),
				BorderThickness = new Thickness(1),
				Margin = new Thickness(3, 3, 0, 3),
				Child = this.ColorIndicator
			};
		}
		/// <summary>
		/// Creates the Inline Editor control.
		/// </summary>
		/// <returns>The control as a FrameworkElement.</returns>
		protected override FrameworkElement CreateInlineEditControl()
		{
			var box = (AutoCompleteComboBox)base.CreateInlineEditControl();
			box.ValueMemberBinding = new System.Windows.Data.Binding("ObjectValue")
				{
					Converter = new KnownColorValueConverter()
				};
			box.MinimumPopulateDelay = 0;
			box.ItemTemplate = (DataTemplate)XamlReader.Load(
					@"<DataTemplate xmlns=""http://schemas.microsoft.com/client/2007"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" xmlns:hssData=""clr-namespace:HSS.Xaml.UI.Data;assembly=SLG50"">
						<Grid>
							<Grid.Resources>
								<hssData:KnownColorValueConverter x:Key=""knownColorValueConverter""/>
							</Grid.Resources>
							<Grid.ColumnDefinitions>
								<ColumnDefinition Width=""20"" />
								<ColumnDefinition />
							</Grid.ColumnDefinitions>
							<Border CornerRadius=""2"" 												
									Background=""White""
									BorderBrush=""Black"" 
									BorderThickness=""1""
									Margin=""1,1,1,1"" >
								<Rectangle Margin=""0"" Fill=""{Binding Path=ObjectValue, Converter={StaticResource knownColorValueConverter} }""/>
							</Border>
							<TextBlock Margin=""4,0,1,0"" Text=""{Binding ObjectDisplay}"" Grid.Column=""1""/>
						</Grid>
					</DataTemplate>");
			return box;
		}
		/// <summary>
		/// Updates the editor with the new value.
		/// </summary>
		/// <param name="newValue">The new value.</param>
		protected override void UpdateInlineEditControl(object newValue)
		{
			this.SetSelectedColor(newValue);
		}
		/// <summary>
		/// Gets the current value held by the control.
		/// </summary>
		/// <returns>The object.</returns>
		protected override object GetControlValue()
		{
			var color = this.GetSelectedColor();
			this.SetSelectedColor(color);
			return color;
		}
		/// <summary>
		/// Begin the editing process.
		/// </summary>
		protected override void OnBeginEdit()
		{
			base.OnBeginEdit();
			if (null != this.Control)
			{
				if (null != this.Object)
				{
					this.Control.Text = colorConverter.ConvertToString(this.Object);
					this.SetSelectedColor(this.Object);
				}
			}
		}
		/// <summary>
		/// Retrieve the list of <see cref="KnownColor"/> for the ComboBox
		/// </summary>
		/// <returns>The collection of <see cref="KnownColors"/>.</returns>
		protected override IEnumerable<object> GetListItems()
		{
			return KnownColors.KnownColorsList.ToArray();
		}
		/// <summary>
		/// Updates the displayed control with the new value.
		/// </summary>
		/// <param name="newValue">The new value.</param>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Windows.Controls.TextBox.set_Text(System.String)")]
		protected override void UpdateDisplayControl(object newValue)
		{
			var displayText = this.ValueToString(newValue);
			if (displayText.StartsWith("#", System.StringComparison.OrdinalIgnoreCase))
			{
				var kcolor = KnownColors.KnownColorFromColor((Color)newValue);
				if (kcolor != KnownColor.UnknownColor)
					displayText = kcolor.ToString() + " (" + displayText + ")";
			}
			((TextBox)this.DisplayControl).Text = displayText;
		}
		#endregion

		#region Methods
		void SetSelectedColor(object value)
		{
			if (null != value && value is Color)
				this.SetSelectedColor((Color)value);
		}
		void SetSelectedColor(Color value)
		{
			if (null != value)
				this.SelectedColor = value;
			if (null != this.ColorIndicator)
				this.ColorIndicator.Fill = new SolidColorBrush(this.SelectedColor);
		}
		Color GetSelectedColor()
		{
			var color = Color.FromArgb(0, 0, 0, 0);

			if (null != this.Object)
			{
				color = (Color)this.Object;

				if (null != this.Control.SelectedItem)
				{
					var item = (ComboBoxItemObject)this.Control.SelectedItem;
					color = (Color)(KnownColor)item.ObjectValue;
				}
				else if (!string.IsNullOrEmpty(this.Control.Text))
				{
					color = (Color)colorConverter.ConvertFromString(this.Control.Text);
				}
			}

			return color;
		}
		#endregion
	}
	#endregion
}
